package multiNyID.MarkerModel;

/*
 * class MarkerModelNyID
 *
 * bikin kelas untuk menghubungkan antara marker dengan objek
 * objek ------> model
 *          |--> pointer
 *          |--> kumpulan bidak
 * --------------------------------------------------------------------------------
 * Based On NyARToolkit The Java edition ARToolKit class library.
 * modified from class MarkerModel - Andrew Davison [ad@fivedots.coe.psu.ac.th]
 *
 * @author whe_green@yahoo.co.id
 * Analisis Metode Occlusion Based Pada Augmented Reality
 * Studi Kasus Interaksi dengan Objek Virtual Secara Realtime
 * Menggunakan Gerakan Tangan
 *
 * Institut Teknologi Telkom
 * Fakultas Informatika 2007
 * Bandung Indonesia
 *
 * nyargreen.wordpress.com
 */

import multiNyID.Objek.PropManager;
import javax.media.j3d.*;
import javax.vecmath.*;


public class ManipulasiModel
{
  private Switch visSwitch;           // for changing the model's visibility
  private BranchGroup modelBG;
  private PropManager modelPropMan; // untuk ngatur gridTG
  //untuk meload model format lain menggunakan propManager



  public ManipulasiModel(String modelFnm, double scale, boolean hasCoords)
  // load the model, rotating and scaling it
  {
    TransformGroup modelTG;    // untuk nampilin objek model
   
    this.modelPropMan = new PropManager(modelFnm, hasCoords);

    // get the TG for the prop (model)
    TransformGroup propTG = this.modelPropMan.getTG();

    // rotate and scale the prop
    Transform3D modelT3d = new Transform3D();
    modelT3d.rotX( Math.PI/2.0 );
         // the prop lies flat on the marker; rotate forwards 90 degrees so it is standing
    Vector3d scaleVec = calcScaleFactor(propTG, scale);   // scale the prop
    modelT3d.setScale( scaleVec );

    modelTG = new TransformGroup(modelT3d);
    modelTG.addChild(propTG);
    bikinHierarki(modelTG);

  }  // end of loadModel()


  //untuk meload model j3d menggunakan propManager
  public ManipulasiModel(BranchGroup sceneGroup, double scale)
  // load the model, rotating and scaling it
  {
    TransformGroup modelTG;    // untuk nampilin objek model
    this.modelPropMan = new PropManager(sceneGroup);

    // get the TG for the prop (model)
    TransformGroup propTG = this.modelPropMan.getTG();

    // rotate and scale the prop
    Transform3D modelT3d = new Transform3D();
    modelT3d.rotX( Math.PI/2.0 );
         // the prop lies flat on the marker; rotate forwards 90 degrees so it is standing
    Vector3d scaleVec = calcScaleFactor(propTG, scale);   // scale the prop
    modelT3d.setScale( scaleVec );

    modelTG = new TransformGroup(modelT3d);
    modelTG.addChild(propTG);
    bikinHierarki(modelTG);

  }  // end of loadModel()


  private Vector3d calcScaleFactor(TransformGroup modelTG, double scale)
  // Scale the prop based on its original bounding box size
  {
     BoundingBox boundbox = new BoundingBox( modelTG.getBounds() );
//     System.out.println(boundbox);

     // obtain the upper and lower coordinates of the box
     Point3d lower = new Point3d();
     boundbox.getLower( lower );
     Point3d upper = new Point3d();
     boundbox.getUpper( upper );


     // store the largest X, Y, or Z dimension and calculate a scale factor
     double max = 0.0;
     if( Math.abs(upper.x - lower.x) > max)
       max = Math.abs(upper.x - lower.x);

     if( Math.abs(upper.y - lower.y) > max)
       max = Math.abs(upper.y - lower.y);

     if( Math.abs(upper.z - lower.z) > max)
       max = Math.abs(upper.z - lower.z);

     double scaleFactor = scale/max;
     System.out.printf("max dimension: %.3f;  scale factor: %.3f\n", max, scaleFactor);

     // limit the scaling so that a big model isn't scaled too much
     if( scaleFactor < 0.0005 ){
         scaleFactor = 0.0005;
      }
      System.out.println("skaLA = "+scaleFactor);
     return new Vector3d(scaleFactor, scaleFactor, scaleFactor);
  }  // end of calcScaleFactor()


  private void bikinHierarki(TransformGroup modelTG){
    // create switch for model visibility
    visSwitch = new Switch();
    visSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
    visSwitch.addChild( modelTG );
    visSwitch.setWhichChild( Switch.CHILD_NONE );   // make invisible
    // create transform group for positioning the model
    modelBG = new BranchGroup();
    modelBG.setCapability(BranchGroup.ALLOW_DETACH);
    modelBG.addChild(visSwitch);
  }

    public void switchOn(int i){
        visSwitch.setWhichChild(i);
    }

    public Switch getVisSwitch() {
        return visSwitch;
    }

    public BranchGroup getModelBG() {
        return modelBG;
    }

    public PropManager getModelPropMan() {
        return this.modelPropMan;
    }


    public void setPosObjekGrid(){       
       this.modelPropMan.awalObjekGrid();        
    }


}